home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 39 / Amiga Format CD39 (1999-04-13)(Future Publishing)(GB)[!][issue 1999-05].iso / -seriously_amiga- / graphics / ripley / source / motion.c < prev    next >
C/C++ Source or Header  |  1999-03-02  |  7KB  |  237 lines

  1. /* motion.c, motion vector decoding                                         */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5. /*
  6.  * Disclaimer of Warranty
  7.  *
  8.  * These software programs are available to the user without any license fee or
  9.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  10.  * any and all warranties, whether express, implied, or statuary, including any
  11.  * implied warranties or merchantability or of fitness for a particular
  12.  * purpose.  In no event shall the copyright-holder be liable for any
  13.  * incidental, punitive, or consequential damages of any kind whatsoever
  14.  * arising from the use of these programs.
  15.  *
  16.  * This disclaimer of warranty extends to the user of these programs and user's
  17.  * customers, employees, agents, transferees, successors, and assigns.
  18.  *
  19.  * The MPEG Software Simulation Group does not represent or warrant that the
  20.  * programs furnished hereunder are free of infringement of any third-party
  21.  * patents.
  22.  *
  23.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  24.  * are subject to royalty fees to patent holders.  Many of these patents are
  25.  * general enough such that they are unavoidable regardless of implementation
  26.  * design.
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31.  
  32. #include "config.h"
  33. #include "global.h"
  34.  
  35. /* private prototypes */
  36. static void decode_motion_vector _ANSI_ARGS_((int *pred, int r_size, int motion_code,
  37.   int motion_residualesidual, int full_pel_vector));
  38.  
  39. /* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */
  40. void motion_vectors(PMV,dmvector,
  41.   motion_vertical_field_select,s,motion_vector_count,mv_format,h_r_size,v_r_size,dmv,mvscale)
  42. int PMV[2][2][2];
  43. int dmvector[2];
  44. int motion_vertical_field_select[2][2];
  45. int s, motion_vector_count, mv_format, h_r_size, v_r_size, dmv, mvscale;
  46. {
  47.   if (motion_vector_count==1)
  48.   {
  49.     if (mv_format==MV_FIELD && !dmv)
  50.     {
  51.       motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = Get_Bits(1);
  52. #ifdef TRACE
  53.       if (Trace_Flag)
  54.       {
  55.         printf("motion_vertical_field_select[][%d] (%d): %d\n",s,
  56.           motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]);
  57.       }
  58. #endif /* TRACE */
  59.     }
  60.  
  61.     motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  62.  
  63.     /* update other motion vector predictors */
  64.     PMV[1][s][0] = PMV[0][s][0];
  65.     PMV[1][s][1] = PMV[0][s][1];
  66.   }
  67.   else
  68.   {
  69.     motion_vertical_field_select[0][s] = Get_Bits(1);
  70. #ifdef TRACE
  71.     if (Trace_Flag)
  72.     {
  73.       printf("motion_vertical_field_select[0][%d] (%d): %d\n",s,
  74.         motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]);
  75.     }
  76. #endif /* TRACE */
  77.     motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  78.  
  79.     motion_vertical_field_select[1][s] = Get_Bits(1);
  80. #ifdef TRACE
  81.     if (Trace_Flag)
  82.     {
  83.       printf("motion_vertical_field_select[1][%d] (%d): %d\n",s,
  84.         motion_vertical_field_select[1][s],motion_vertical_field_select[1][s]);
  85.     }
  86. #endif /* TRACE */
  87.     motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
  88.   }
  89. }
  90.  
  91. /* get and decode motion vector and differential motion vector 
  92.    for one prediction */
  93. void motion_vector(PMV,dmvector,
  94.   h_r_size,v_r_size,dmv,mvscale,full_pel_vector)
  95. int *PMV;
  96. int *dmvector;
  97. int h_r_size;
  98. int v_r_size;
  99. int dmv; /* MPEG-2 only: get differential motion vectors */
  100. int mvscale; /* MPEG-2 only: field vector in frame pic */
  101. int full_pel_vector; /* MPEG-1 only */
  102. {
  103.   int motion_code, motion_residual;
  104.  
  105.   /* horizontal component */
  106.   /* ISO/IEC 13818-2 Table B-10 */
  107.   motion_code = Get_motion_code();
  108.  
  109.   motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0;
  110.  
  111. #ifdef TRACE
  112.   if (Trace_Flag)
  113.   {
  114.     if (h_r_size!=0 && motion_code!=0)
  115.     {
  116.       printf("motion_residual (");
  117.       Print_Bits(motion_residual,h_r_size,h_r_size);
  118.       printf("): %d\n",motion_residual);
  119.     }
  120.   }
  121. #endif /* TRACE */
  122.  
  123.  
  124.   decode_motion_vector(&PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector);
  125.  
  126.   if (dmv)
  127.     dmvector[0] = Get_dmvector();
  128.  
  129.  
  130.   /* vertical component */
  131.   motion_code     = Get_motion_code();
  132.   motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0;
  133.  
  134. #ifdef TRACE
  135.   if (Trace_Flag)
  136.   {
  137.     if (v_r_size!=0 && motion_code!=0)
  138.     {
  139.       printf("motion_residual (");
  140.       Print_Bits(motion_residual,v_r_size,v_r_size);
  141.       printf("): %d\n",motion_residual);
  142.     }
  143.   }
  144. #endif /* TRACE */
  145.  
  146.   if (mvscale)
  147.     PMV[1] >>= 1; /* DIV 2 */
  148.  
  149.   decode_motion_vector(&PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector);
  150.  
  151.   if (mvscale)
  152.     PMV[1] <<= 1;
  153.  
  154.   if (dmv)
  155.     dmvector[1] = Get_dmvector();
  156.  
  157. #ifdef TRACE
  158.   if (Trace_Flag)
  159.     printf("PMV = %d,%d\n",PMV[0],PMV[1]);
  160. #endif /* TRACE */
  161. }
  162.  
  163. /* calculate motion vector component */
  164. /* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
  165. /* Note: the arithmetic here is more elegant than that which is shown 
  166.    in 7.6.3.1.  The end results (PMV[][][]) should, however, be the same.  */
  167.  
  168. static void decode_motion_vector(pred,r_size,motion_code,motion_residual,full_pel_vector)
  169. int *pred;
  170. int r_size, motion_code, motion_residual;
  171. int full_pel_vector; /* MPEG-1 (ISO/IEC 11172-1) support */
  172. {
  173.   int lim, vec;
  174.  
  175.   lim = 16<<r_size;
  176.   vec = full_pel_vector ? (*pred >> 1) : (*pred);
  177.  
  178.   if (motion_code>0)
  179.   {
  180.     vec+= ((motion_code-1)<<r_size) + motion_residual + 1;
  181.     if (vec>=lim)
  182.       vec-= lim + lim;
  183.   }
  184.   else if (motion_code<0)
  185.   {
  186.     vec-= ((-motion_code-1)<<r_size) + motion_residual + 1;
  187.     if (vec<-lim)
  188.       vec+= lim + lim;
  189.   }
  190.   *pred = full_pel_vector ? (vec<<1) : vec;
  191. }
  192.  
  193.  
  194. /* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */
  195. void Dual_Prime_Arithmetic(DMV,dmvector,mvx,mvy)
  196. int DMV[][2];
  197. int *dmvector; /* differential motion vector */
  198. int mvx, mvy;  /* decoded mv components (always in field format) */
  199. {
  200.   if (picture_structure==FRAME_PICTURE)
  201.   {
  202.     if (top_field_first)
  203.     {
  204.       /* vector for prediction of top field from bottom field */
  205.       DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  206.       DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
  207.  
  208.       /* vector for prediction of bottom field from top field */
  209.       DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  210.       DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
  211.     }
  212.     else
  213.     {
  214.       /* vector for prediction of top field from bottom field */
  215.       DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
  216.       DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
  217.  
  218.       /* vector for prediction of bottom field from top field */
  219.       DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
  220.       DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
  221.     }
  222.   }
  223.   else
  224.   {
  225.     /* vector for prediction from field of opposite 'parity' */
  226.     DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
  227.     DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
  228.  
  229.     /* correct for vertical field shift */
  230.     if (picture_structure==TOP_FIELD)
  231.       DMV[0][1]--;
  232.     else
  233.       DMV[0][1]++;
  234.   }
  235. }
  236.  
  237.